
#include <string.h>
#include <stdio.h>
#include <stdarg.h>


#define tc_log(_fmt_, ...) \
        printf("[TC][%s:%d][%s] "_fmt_"\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#define tc_log_err(_fmt_, ...) \
        printf("[TC][ERR][%s:%d][%s] "_fmt_"\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)


static void hexdump(const void *data, size_t size, const char *str, ...)
{
    char t_str[128];
    char hexByte[4];
    char hexLine[50];
    char charByte[2];
    char charLine[18];
    unsigned int i;

    va_list args;
    va_start(args, str);
    int len = vsnprintf(t_str, sizeof(t_str), str, args);
    va_end(args);
    printf("%.*s\r\n", len, t_str);

    for (i = 0; i < size; i++) {
        if (i % 16 == 0) {
            hexLine[0] = 0;
            charLine[0] = 0;
        }
        if (i % 16 == 8) {
            strcat(hexLine, " ");
            strcat(charLine, " ");
        }
        snprintf(hexByte, sizeof(hexByte), " %02x", ((unsigned char *) data)[i]);
        strcat(hexLine, hexByte);
        if (((unsigned char *) data)[i] < 32 || ((unsigned char *) data)[i] > 126) {
            strcat(charLine, ".");
        } else {
            snprintf(charByte, sizeof(charByte), "%c", ((unsigned char *) data)[i]);
            strcat(charLine, charByte);
        }
        if (i % 16 == 15 || i == size - 1) {
            printf("%04x:%-49s  %s\r\n", i & ~15, hexLine, charLine);
        }
    }
}

static void intdump(const void *data, size_t size, const char *str, ...)
{
    char t_str[128];
    char hexByte[6];
    char hexLine[50];
    unsigned int i;

    va_list args;
    va_start(args, str);
    int len = vsnprintf(t_str, sizeof(t_str), str, args);
    va_end(args);
    printf("%.*s\r\n", len, t_str);

    for (i = 0; i < size; i++) {
        if (i % 8 == 0) {
            hexLine[0] = 0;
        }
        if (i % 8 == 4) {
            strcat(hexLine, " ");
        }
        snprintf(hexByte, sizeof(hexByte), " %d", ((unsigned int *) data)[i]);
        strcat(hexLine, hexByte);
        if (i % 8 == 7 || i == size - 1) {
            printf("%04x:%-41s\r\n", i & ~15, hexLine);
        }
    }
}

char * removeDuplicates(char * s){
    int final_idx, walk_idx;
    int same, end, numsSize;

    tc_log("in s %s", s);

    numsSize = strlen(s);
    if (numsSize <= 1) {
        return s;
    }

    do {
        end = 1;
        same = 0;

        numsSize = strlen(s);
        tc_log("numsSize %d", numsSize);

        for (final_idx = 0, walk_idx = 1; walk_idx < numsSize; ++walk_idx) {

            tc_log("[%d] %c [%d] %c", final_idx, s[final_idx], walk_idx, s[walk_idx]);

            if (s[walk_idx] != s[final_idx]) {
                if (!same) {
                    final_idx++;
                }

                s[final_idx] = s[walk_idx];
                tc_log("[%d] %c [%d] %c s %s", final_idx, s[final_idx], walk_idx, s[walk_idx], s);

                same = 0;
            } else {
                same = 1;
                end = 0;
            }
        }

        tc_log("same %d final_idx %d", same, final_idx);

        if (final_idx == 0) {
            s[1] = '\0';
            return s;
        }

        if (same) {
            s[final_idx] = '\0';
        } else {
            s[final_idx + 1] = '\0';
        }

        tc_log("end %d s %s", end, s);
    }
    while (!end);

    tc_log("return s %s", s);

    return s;
}

int main(int argc, char const *argv[])
{
    tc_log("********************");
    tc_log("new start @ %s %s", __DATE__, __TIME__);
    tc_log("********************");

    char *st;
    char *s[] = {
        "abbaca",
        "aaaaaaaaa",
        "aababaab",
    };
    char *exp[] = {
        "ca",
        "",
        "ba",
    };

    tc_log("array size %d", sizeof(s)/sizeof(char *));

    for (int i = 0; i < (sizeof(s)/sizeof(char *)); ++i) {

        st = malloc(strlen(s[i]));
        strcpy(st, s[i]);

        st = removeDuplicates(st);
        if (!strcmp(st, exp[i])) {
            tc_log("s %s success", st);
        } else {
            tc_log("s %s failed", st);
        }
        free(st);
    }

    tc_log("exit");
    return 0;
}

